// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html


import { RoomUser } from "../bean/GameBean";
import { GlobalBean } from "../bean/GlobalBean";
import GamePlayerController from "../pfb/GamePlayerController";


const { ccclass, property } = cc._decorator;

@ccclass
export default class GameLayoutController extends cc.Component {

    @property(cc.Node)
    Layout: cc.Node = null;  // 分数布局容器
    @property(cc.Prefab)
    playerScorePfb: cc.Prefab = null;  // player_score_pfb 预制体

    // 存储所有玩家控制器的映射
    private playerControllerMap: Map<string, GamePlayerController> = new Map();

    // 持久化记录：哪些用户已经死亡（用于断线/重连后仍需显示死亡图标）
    private deadUserIds: Set<string> = new Set();

    // onLoad () {} 

    onLoad() {
        // 初始化时不自动创建界面，等待游戏数据
    }

    start() {
        // 不在start中自动创建，等待外部调用
    }

    /**
     * 清理分数显示界面
     */
    clearScoreView() {
        if (this.Layout) {
            this.Layout.removeAllChildren();
            // 清空玩家控制器映射
            this.playerControllerMap.clear();
            // 清空死亡记录
            this.deadUserIds.clear();
        }
    }

    /**
     * 创建分数显示界面
     * 支持砖块派对游戏和传统游戏两种数据格式
     */
    createScoreView() {


        // 检查必要的组件是否存在
        if (!this.Layout) {
            console.error("scoreLayout 未设置！请在编辑器中拖拽布局节点到 scoreLayout 属性");
            return;
        }

        if (!this.playerScorePfb) {
            console.error("playerScorePfb 未设置！请在编辑器中拖拽预制体到 playerScorePfb 属性");
            return;
        }

        // 清空现有的子节点，避免重复创建
        this.Layout.removeAllChildren();


        this.createBrickPartyView();



    }


    /**
     * 创建砖块派对游戏的界面
     */
    private createBrickPartyView() {
        const gameStartData = GlobalBean.GetInstance().noticeStartGame;
        const playerDataArray = gameStartData.users;


        // 根据playerNumber排序，确保按照1,2,3,4的顺序显示
        const sortedPlayerData = [...playerDataArray].sort((a, b) => a.playerNumber - b.playerNumber);

        // 根据后端playerData生成分数预制体
        for (let i = 0; i < sortedPlayerData.length; i++) {
            const playerData = sortedPlayerData[i];

            // 实例化预制体
            const item = cc.instantiate(this.playerScorePfb);
            this.Layout.addChild(item);

            // 获取预制体的控制器组件
            const playerController = item.getComponent(GamePlayerController);
            if (playerController) {
                // 创建兼容的RoomUser数据（用于显示基本信息）
                // 注意：砖块派对的数据结构直接包含这些字段
                const compatibleUser: RoomUser = {
                    userId: playerData.userId,
                    nickName: playerData.nickName || `Player${playerData.playerNumber}`, // 使用实际昵称
                    avatar: playerData.avatar || "", // 使用实际头像
                    pos: playerData.playerNumber,
                    coin: playerData.coin || 0, // 使用实际金币
                    status: playerData.bpStatus || 0, // 砖块派对状态
                    score: 0,
                    rank: playerData.rank,
                    playerNumber: 0,
                    x: 0,
                    y: 0,
                    playerType: "",
                    surviveTime: 0
                };


                // 设置基本用户数据
                playerController.setData(compatibleUser);

                // 只设置playerTypeImage，不生成动物预制体（动物预制体由GamePageController统一管理）
                playerController.setPlayerTypeImageOnly(playerData.playerType);

                // 将控制器添加到映射中
                this.playerControllerMap.set(playerData.userId, playerController);
                // 若该玩家在进入时就已死亡（bpStatus == 2），记录并显示死亡图标
                if (playerData.bpStatus === 2) {
                    this.deadUserIds.add(playerData.userId);
                    playerController.showPlayerStatus(7);
                }

            } else {
                console.error(`第${i}个预制体没有找到 GamePlayerController 组件`);
            }
        }
    }

    /**
     * 创建传统游戏的界面（保持原有逻辑）
     */
    private createTraditionalView() {
        // 获取后端传回来的用户数据 - 使用原始顺序确保所有玩家看到相同的排列
        // 不再使用adjustUserData()方法，因为它会将当前玩家移到第一位，导致每个玩家看到不同的排列
        let users: RoomUser[] = GlobalBean.GetInstance().noticeStartGame.users;

        // 使用基于房间ID的伪随机排列，确保所有玩家看到相同的排列顺序
        const seed = GlobalBean.GetInstance().noticeStartGame.roomId;
        users = this.shuffleArrayWithSeed(users, seed);

        // 根据后端用户数据生成分数预制体
        for (let i = 0; i < users.length; i++) {
            const user = users[i];


            // 实例化预制体
            const item = cc.instantiate(this.playerScorePfb);
            this.Layout.addChild(item);

            // 获取预制体的控制器组件
            const playerController = item.getComponent(GamePlayerController);
            if (playerController) {
                // 设置用户数据到预制体
                playerController.setData(user);

                // 将控制器添加到映射中
                this.playerControllerMap.set(user.userId, playerController);
               
            } else {
                console.error(`第${i}个预制体没有找到 GamePlayerController 组件`);
            }
        }
    }

    /**
     * 基于种子的伪随机数生成器（简单的线性同余生成器）
     */
    private seededRandom(seed: number): () => number {
        let current = seed;
        return function () {
            current = (current * 1664525 + 1013904223) % 4294967296;
            return current / 4294967296;
        };
    }

    /**
     * 使用种子随机打乱数组顺序，确保相同种子产生相同的排列结果
     */
    private shuffleArrayWithSeed<T>(array: T[], seed: number): T[] {
        const shuffled = [...array]; // 创建副本，避免修改原数组
        const random = this.seededRandom(seed);

        for (let i = shuffled.length - 1; i > 0; i--) {
            const j = Math.floor(random() * (i + 1));
            [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
        }
        return shuffled;
    }

    /**
     * 显示玩家状态（死亡、断线、退出、重连）
     * @param userId 用户ID
     * @param eventType 事件类型 (7-死亡, 8-断线, 9-退出, 10-重连)
     */
    public showPlayerStatus(userId: string, eventType: number): void {
       
        // 按事件维护死亡持久化记录
        if (eventType === 7) { // 死亡
            this.deadUserIds.add(userId);
        } else if (eventType === 9) { // 退出
            // 退出后也认为不再需要显示死亡状态（可按需求调整）
            this.deadUserIds.delete(userId);
        }

        const playerController = this.playerControllerMap.get(userId);
        if (playerController) {
            playerController.showPlayerStatus(eventType);
            // 特殊处理：重连(10)事件应当保留死亡图标
            if (eventType === 10 && this.deadUserIds.has(userId)) {
                playerController.showPlayerStatus(7);
            }
        } else {
            console.warn(`未找到用户 ${userId} 的玩家控制器`);
           
        }
    }

    /**
     * 根据OnlineStateEvent显示玩家状态（用于断线重连）
     * @param userId 用户ID
     * @param onlineStateEvent OnlineStateEvent值
     */
    public showPlayerStatusByOnlineStateEvent(userId: string, onlineStateEvent: number): void {
       

        const playerController = this.playerControllerMap.get(userId);
        if (playerController) {
            playerController.showStatusByOnlineStateEvent(onlineStateEvent);
            
        } else {
            console.warn(`未找到用户 ${userId} 的玩家控制器`);
           
        }
    }

    /**
     * 处理断线重连时的用户数据
     * @param users 用户数据数组
     */
    public handleReconnectionUserData(users: any[]): void {
       
        if (!users || users.length === 0) {
            console.warn("用户数据为空，无法更新玩家状态");
            return;
        }

        for (const user of users) {
            // 兼容大小写不同的字段名
            const onlineStateEvent = user.onlineStateEvent || user.OnlineStateEvent;
            if (user.userId && typeof onlineStateEvent === 'number') {
                // 同步死亡标记（2=死亡/淘汰）
                if (user.bpStatus === 2) {
                    this.deadUserIds.add(user.userId);
                }

                // 优先级：退出(9) > 离线(8) > 死亡(bpStatus=2) > 在线(10)
                const controller = this.playerControllerMap.get(user.userId);
                if (!controller) {
                    console.warn(`未找到用户 ${user.userId} 的玩家控制器`);
                    continue;
                }

                if (onlineStateEvent === 9) {
                    // 退出时优先级最高，且不再显示死亡
                    this.deadUserIds.delete(user.userId);
                    controller.showPlayerStatus(9);
                    continue;
                }

                if (onlineStateEvent === 8) {
                    // 离线优先于死亡显示
                    controller.showPlayerStatus(8);
                    continue;
                }

                if (this.deadUserIds.has(user.userId)) {
                    // 已死亡：仅在在线(10)时显示死亡
                    controller.showPlayerStatus(7);
                    continue;
                }

                // 其余情况按在线状态显示（断线/在线）
                controller.showStatusByOnlineStateEvent(onlineStateEvent);
            } else {
                console.warn(`用户数据不完整: userId=${user.userId}, onlineStateEvent=${onlineStateEvent}`);
            }
        }
    }

    /**
     * 隐藏指定玩家的断线状态
     * @param userId 用户ID
     */
    public hideDisconnectStatus(userId: string): void {
        const playerController = this.playerControllerMap.get(userId);
        if (playerController) {
            playerController.hideDisconnectStatus();
         
        } else {
            console.warn(`未找到用户 ${userId} 的玩家控制器`);
        }
    }

    /**
     * 隐藏指定玩家的所有状态标识（死亡、断线、退出）
     * @param userId 用户ID
     */
    public hideAllPlayerStatus(userId: string): void {
        const playerController = this.playerControllerMap.get(userId);
        if (playerController) {
            playerController.hideAllStatusNodes();
            // 从死亡记录中移除（因为玩家重连且存活）
            this.deadUserIds.delete(userId);
            
        } else {
            console.warn(`未找到用户 ${userId} 的玩家控制器`);
        }
    }

    /**
     * 调试方法：列出所有玩家控制器
     */
    public debugPlayerControllers(): void {
       

       
    }

    // update (dt) {}
}
